package com.systop.common.modules.dept.webapp;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.struts2.interceptor.validation.SkipValidation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
import com.opensymphony.xwork2.validator.annotations.Validations;
import com.opensymphony.xwork2.validator.annotations.ValidatorType;
import com.rbcs.base.item.service.ItemManager;
import com.rbcs.base.model.Item;
import com.systop.common.modules.dept.DeptConstants;
import com.systop.common.modules.dept.model.Dept;
import com.systop.common.modules.dept.service.DeptManager;
import com.systop.common.modules.dept.service.DeptSerialNoManager;
import com.systop.core.ApplicationException;
import com.systop.core.Constants;
import com.systop.core.util.RequestUtil;
import com.systop.core.webapp.struts2.action.ExtJsCrudAction;

/**
 * 部门管理Action
 * 
 * @author Sam Lee
 * 
 */
@SuppressWarnings({ "serial", "unchecked", "rawtypes" })
@Controller
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class DeptAction extends ExtJsCrudAction<Dept, DeptManager> {

	/** 部门序列号管理器 */
	private DeptSerialNoManager serialNoManager;

	@Autowired
	private ItemManager itemManager;

	/** AJAX调用返回变量(JSON) */
	private List<Map<String, Object>> depts;

	/** 父部门ID */
	private Integer parentId;

	// 财务科目ID
	private Integer itemId;

	private Integer[] selectedItemIds;

	private List<Item> unSelectedItems;

	/**
	 * 部门查询。根据指定的上级部门id(通过{@link #parentId}属性)，查询下级部门。 如果{@link #parentId}
	 * 为null,则查询顶级部门（没有上级部门的）
	 */
	@Override
	@SkipValidation
	public String index() {
		return INDEX;
	}

	/**
	 * Build a tree as JSON format.
	 */
	public String deptTree() {
		if (RequestUtil.isJsonRequest(getRequest())) {
			List<Dept> tops = getManager().getDeptsByParentId(null);
			depts = new ArrayList<Map<String, Object>>();
			for (Dept dept : tops) {
				Map<String, Object> top = toMap(dept);
				top = buildTreeByParent(top, true);
				depts.add(top);
			}
			return JSON;
		}
		return INDEX;
	}

	/**
	 * 返回部门树形列表，每一个部门用一个Map表示，子部门用Map的'childNodes'key挂接一个List
	 * 
	 * @param parent
	 *            父部门
	 * @param nested
	 *            是否递归查询子部门
	 * @return
	 */
	private Map buildTreeByParent(Map<String, Object> parent, boolean nested) {
		if (parent != null) {
			List<Dept> subs = getManager().getDeptsByParentId(
					(Integer) parent.get("id"));
			List childs = new ArrayList();
			for (Dept dept : subs) {
				Map child = toMap(dept);
				if (nested) { // 递归查询子部门
					child = buildTreeByParent(child, nested);
				}
				childs.add(child);
			}
			if (!childs.isEmpty()) {
				parent.put("children", childs);
				parent.put("leaf", false);
			} else {
				parent.put("leaf", true);
			}
		}
		return parent;
	}

	private Map<String, Object> toMap(Dept dept) {
		Map<String, Object> map = null;
		if (dept != null) {
			map = new HashMap<String, Object>();
			map.put("id", dept.getId());
			map.put("text", dept.getName());
			map.put("descn", dept.getDescn());
		}
		return map;
	}

	/**
	 * 覆盖父类，处理父部门ID为{@link DeptConstants#TOP_DEPT_ID}的情况。
	 */
	@Override
	@Validations(requiredStrings = { @RequiredStringValidator(type = ValidatorType.SIMPLE, fieldName = "model.name", message = "部门名称是必须的.") })
	public String save() {
		try {
			Dept dept = getModel();
			if (parentId != null) {
				Dept parent = getManager().get(parentId);
				if (parent != null) {
					dept.setParent(parent);
					parent.setIsLeaf(Constants.NO);
				}
			}
			getManager().save(dept);
			return SUCCESS;
		} catch (ApplicationException e) {
			addActionError(e.getMessage());
			return INPUT;
		}
	}

	public String editConfig() {
		unSelectedItems = itemManager.getUnSelectedByDept(getModel());
		return INPUT;
	}

	/**
	 * 部门预算科目配置
	 * 
	 * @return
	 */
	public String saveConfig() {
		try {
			Dept dept = getModel();
			// 每次都先删除原有科目
			dept.setItems(new ArrayList());
			getManager().save(dept);
			if (selectedItemIds != null) {
				for (Integer id : selectedItemIds) {
					dept.getItems().add(new Item(id));
				}
			}
			getManager().save(dept);
			return SUCCESS;
		} catch (ApplicationException e) {
			addActionError(e.getMessage());
			return INPUT;
		}
	}

	/**
	 * 处理parentDept为null的情况
	 */
	@Override
	@SkipValidation
	public String edit() {
		return INPUT;
	}

	public String remove() {
		return super.remove();
	}

	/**
	 * 删除财务科目
	 * 
	 * @return
	 */
	public String removeItem() {
		if (getModel() != null && getModel().getId() != null) {
			if (itemId != null) {
				Item item = getManager().getDao().get(Item.class, itemId);
				getModel().getItems().remove(item);
				getManager().save(getModel());
				addActionMessage("删除财务科目成功");
			}
		}
		return INPUT;
	}

	/**
	 * 重置所有部门编号
	 */
	@SkipValidation
	public String updateSerialNo() {
		serialNoManager.updateAllSerialNo();
		return SUCCESS;
	}

	public DeptSerialNoManager getSerialNoManager() {
		return serialNoManager;
	}

	@Autowired(required = true)
	public void setSerialNoManager(DeptSerialNoManager serialNoManager) {
		this.serialNoManager = serialNoManager;
	}

	public List<Map<String, Object>> getDepts() {
		return depts;
	}

	public Integer getParentId() {
		return parentId;
	}

	public void setParentId(Integer parentId) {
		this.parentId = parentId;
	}

	public void setItemId(Integer itemId) {
		this.itemId = itemId;
	}

	public List<Item> getUnSelectedItems() {
		return unSelectedItems;
	}

	public Integer[] getSelectedItemIds() {
		return selectedItemIds;
	}

	public void setSelectedItemIds(Integer[] selectedItemIds) {
		this.selectedItemIds = selectedItemIds;
	}
}
